import glob
import sys
import os
cwd = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(os.path.join(cwd, "../controller/"))
import action
import xml.dom.minidom as minidom

# http://security.stackexchange.com/questions/6998/best-way-to-triage-crashes-found-via-fuzzing-on-linux

class Exploitable():
    def __init__(self, target_prog=None):
        """
        Declare crash analysis tool. Linux tool that will be used will be Valgrind
        @param target_prog: Program that was being fuzzed that crashed and could be potentially exploited :)
        """
        self.action = action.Action()
        self.crash_cmd = "valgrind --xml=yes --xml-file="
        if target_prog: 
            self.target_prog = target_prog
        self.counter = 0
        #key words for processing valgrind crash analysis. located in xml at: <error><kind>...</kind></error>
        self.exploitability_index = {"Leak_DefinitelyLost": "ProbablyNot",
                                     "Leak_PossiblyLost": "ProbablyNot",
                                     "Leak_IndirectlyLost": "ProbablyNot",
                                     "Leak_StillReachable": "ProbablyNot",
                                     "InvalidRead": "PotentiallyExploitable",
                                     "InvalidWrite": "Exploitable",
                                     "InvalidFree": "Exploitable",
                                     "InvalidJump": "PotentiallyExploitable",
                                     "UninitCondition": "PotentiallyExploitable",
                                     "UninitValue": "PotentiallyExploitable"}
        
    def analyze(self, directory, filetype="pdf", target_prog=None, timeout=10):
        """
        @param directory: direcotry where files that cause crashes are located
        @param filetype: Type of file (pdf, mp3, tiff, etc..)
        @param target_prog: Program that was being fuzzed that crashed and could be potentially exploited :)
        @param timeout: How long to wait before killing valgrind (sometimes valgrind can take a while)
        """
        if target_prog:
            self.target_prog = target_prog
        if not self.target_prog: 
            return "Error, Did not specify target program"
        
        _filetype = "*." + filetype
        search = os.path.join(directory, _filetype)
        files = glob.glob(search)
        for file in files:
            _crash_cmd = self.crash_cmd + str(file) + ".xml" + " " + str(self.target_prog) + " " + file      
            self.action.run_timed(_crash_cmd, timeout)
    
    def analyze_exploitability(self, directory):
        print "testing..."
        for file in glob.glob(os.path.join(directory, "*.xml")):
            xml_file = minidom.parse(file)
            crash_type = xml_file.getElementsByTagName("kind")[0].firstChild.wholeText
            print crash_type
            #xml_file.getElementsByTagName("kind")[0].firstChild.wholeText
            
            
            
if __name__ == "__main__":
    e = Exploitable("pdftotext")
    e.analyze("/home/username/workspace/dfuzz/trunk/client/results/dfuzz_run1")
    e.analyze_exploitability("/home/username/workspace/dfuzz/trunk/client/results/dfuzz_run1")